package controller

import (
	"io/ioutil"
	"leeframe/internal/pkg/http"
	"leeframe/internal/pkg/logger"
	"leeframe/internal/pkg/trace"
	nethttp "net/http"

	"github.com/go-redis/redis"

	"github.com/gin-gonic/gin"
)

var Ping = new(pingApi)

type pingApi struct{}

// 定义接口，mockgen根据这个生成对应的mock文件
type PingInfoMock interface {
	HttpGetMock(url string) (content []byte, err error)
	RedisPingMock(rdb *redis.Client) (content string, err error)
}

// Info 测试ping
// @Summary 测试ping
// @Description 测试ping
// @Tags 测试接口
// @Accept mpfd
// @Produce json
// @Success 200 {object} http.Response
// @Router /ping [get]
// @Author: lee
// @Date: 2021-11-30 11:19:28
func (a *pingApi) Info(c *gin.Context) {
	var (
		appGin = http.Gin{C: c}
	)

	appGin.Response(http.SUCCESS, "OK", "pong")
}

// InfoMock 测试pingMock
// @Summary 测试pingMock
// @Description 测试pingMock
// @Tags 测试接口
// @Accept mpfd
// @Produce json
// @Param url query string true "请求信息" default(http://www.github.com)
// @Success 200 {object} http.Response{data=string}
// @Router /ping/mock [get]
// @Author: lee
// @Date: 2021-12-24 18:01:32
func (a *pingApi) InfoMock(c *gin.Context) {
	var (
		appGin = http.Gin{C: c}
		url    = c.Query("url")
	)

	content, err := HttpGetMock(url)
	if err != nil {
		appGin.Response(http.ERROR, err.Error(), nil)
		return
	}

	appGin.Response(http.SUCCESS, "OK", string(content))
}

// HttpGetMock
// @Author: lee
// @Date: 2021-12-27 14:58:28
// @Description: mock http get请求
func HttpGetMock(url string) (content []byte, err error) {
	r, err := nethttp.Get(url)
	if err != nil {
		return nil, err
	}
	defer r.Body.Close()

	content, err = ioutil.ReadAll(r.Body)
	if err != nil {
		return nil, err
	}

	return
}

// PingRedisMock 测试PingRedisMock
// @Summary 测试PingRedisMock
// @Description 测试PingRedisMock
// @Tags 测试接口
// @Accept mpfd
// @Produce json
// @Success 200 {object} http.Response{data=string}
// @Router /ping/redis/mock [get]
// @Author: lee
// @Date: 2021-12-27 17:07:57
func (a *pingApi) PingRedisMock(c *gin.Context) {
	var (
		appGin = http.Gin{C: c}
	)

	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password set
		DB:       0,  // use default DB
	})
	content, err := RedisPingMock(rdb)
	if err != nil {
		appGin.Response(http.ERROR, err.Error(), nil)
		return
	}

	appGin.Response(http.SUCCESS, "OK", string(content))
}

// RedisPingMock
// @Author: lee
// @Date: 2021-12-27 18:05:10
// @Description: mock redis ping请求
func RedisPingMock(rdb *redis.Client) (content string, err error) {
	content, err = rdb.Ping().Result()
	return content, err
}

// TraceLog 测试trace log
// @Summary 测试trace log
// @Description 测试trace log
// @Tags 测试接口
// @Accept mpfd
// @Produce json
// @Param X-Request-Id header string false "链路ID"
// @Success 200 {object} http.Response{data=string}
// @Router /ping/trace_log [get]
// @Author: lee
// @Date: 2022-01-06 16:51:11
func (a *pingApi) TraceLog(c *gin.Context) {
	var (
		appGin = http.Gin{C: c}
	)
	traceID := appGin.C.GetString(trace.HeaderKey)

	logger.InfoN(c, "trace_log withcontext: ")

	appGin.Response(http.SUCCESS, "OK", traceID)
}
